home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
glass
/
glass.lha
/
GLASS
/
uflat
/
uflat.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-18
|
13KB
|
516 lines
/*
File: uflat.c
*/
#include <strings.h>
#include <stdio.h>
#include <tmc.h>
#include <cvr.h>
#include "uflatconst.h"
#include "tmcode.h"
#include "utils.h"
/* command line flags */
static int showorig = TRUE;
static int symtabtr = FALSE;
static int anptr = FALSE;
static int stat = FALSE;
/* common variables */
#define infile stdin
#define outfile stdout
FILE *tracestream = stderr;
/* Name of definition to be monitored */
def thedef;
def_list new_defs; /* remaining atoms, basetypes and thedef */
/*
Table of debugging flags plus associated information.
Table is ended by an entry with flagchar '\0'
*/
static dbflag flagtab[] =
{{ 'g', &anptr, "trace lambda removal generation" },
{ 's', &stat, "statistics" },
{ 't', &symtabtr, "symbol table tracing" },
{ '\0', (int *)0, "" },
};
/* Given a symbol 's', search the context for a definition with
* that name, and return a pointer to it.
*/
static ctx_list context;
static def find_def (s)
symbol s;
{ register unsigned int cix;
register unsigned int dix;
for (cix = 0; cix < context -> sz; cix++)
{ register def_list l = context -> arr[cix] -> defs;
for (dix = 0; dix < l -> sz; dix++)
{ register def d = l -> arr[dix];
switch (d -> tag)
{ case TAGDefAtom:
if (d -> DefAtom.atnm == s) return (d);
break;
case TAGDefBasetype:
if (d -> DefBasetype.basename == s) return (d);
break;
case TAGDefVal:
if (d -> DefVal.valnm == s) return (d);
break;
case TAGDefTyp:
if (d -> DefTyp.typnm == s) return (d);
break;
case TAGDefCon:
break;
default:
badtag (d -> tag);
};
};
}
return (defNIL);
};
/* Check if symbol 'nm' occurs in formcon 'fc' */
int occurs_in (nm, fc)
symbol nm;
formcon fc;
{ switch (fc -> tag)
{ case TAGFCSym:
if (fc -> FCSym.sym == nm) return (1);
break;
case TAGFCList:
{ register int ix;
register formcon_list fcs = fc -> FCList.l;
for (ix = 0; ix < fcs -> sz; ix++)
if (occurs_in (nm, fcs -> arr[ix])) return (1);
};
break;
default:
badtag (fc -> tag);
break;
};
return (0);
};
/* Given a symbol 'nm', a value 'sv' and a value 'v', return a copy
* of 'v' with all occurences of 'nm' replaced by a copy of 'sv'.
*/
val_list subs_val_list ();
val subs_val (nm, sv, v)
symbol nm;
val sv;
val v;
{ switch (v -> tag)
{ case TAGVSym:
if (v -> VSym.sym == nm)
{ return (rdup_val (sv));
}
else return (rdup_val (v));
case TAGVLambda:
if (!(occurs_in (nm, v -> VLambda.lpar)))
{ return (new_VLambda (rdup_formcon (v -> VLambda.lpar),
subs_val (nm, sv, v -> VLambda.lval)));
}
else return (rdup_val (v));
case TAGVSigma:
case TAGVSyn:
case TAGVAppset:
{ fprintf (stderr, "Only directional descriptions allowed\n");
exit (1);
};
case TAGVApply:
return (new_VApply (subs_val (nm, sv, v -> VApply.aval),
subs_val (nm, sv, v -> VApply.apar)));
case TAGVWhere:
{ def d;
def_list dl;
def_list nl;
register unsigned int ix;
dl = v -> VWhere.wdefs;
if ((dl == def_listNIL) || (dl -> sz == 0))
return (subs_val (nm, sv, v -> VWhere.wval));
nl = new_def_list ();
room_def_list (nl, dl -> sz);
nl -> sz = dl -> sz;
for (ix=0; ix < dl -> sz; ix++)
{ d = dl -> arr[ix];
if (d -> tag != TAGDefCon)
{ nl -> arr[ix] = rdup_def (d);
}
else
nl -> arr[ix] = new_DefCon
(rdup_orig (d -> DefCon.conorig),
subs_val (nm, sv, d -> DefCon.defcon),
subs_val (nm, sv, d -> DefCon.conas));
};
return (new_VWhere (nl,
subs_val (nm, sv, v -> VWhere.wval)));
};
case TAGVList:
return (new_VList (subs_val_list (nm, sv, v -> VList.l)));
case TAGVAtom:
return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
subs_val (nm, sv, v -> VAtom.atcpar)));
default:
badtag (v -> tag);
};
};
/* Given a symbol 'nm', a value 'sv' and a value list 'vl', return a copy
* of 'vl' with all occurences of 'nm' replaced by a copy of 'sv'.
*/
static val_list subs_val_list (nm, sv, vl)
symbol nm;
val sv;
val_list vl;
{ register unsigned int ix;
val_list nl = new_val_list ();
if (vl == val_listNIL) return (nl);
room_val_list (nl, vl -> sz);
nl -> sz = vl -> sz;
for (ix=0; ix < vl -> sz; ix++)
nl -> arr[ix] = subs_val (nm, sv, vl -> arr[ix]);
return (nl);
};
/* Copy all global basetype and atom definitions */
static copy_basenamedefs (new, old)
def_list new, old;
{ register int ix;
register def d;
for (ix = 0; ix < old -> sz; ix++)
{ d = old -> arr[ix];
switch (d -> tag)
{ case TAGDefAtom:
app_def_list (new, rdup_def (d));
break;
case TAGDefBasetype:
app_def_list (new, rdup_def (d));
break;
case TAGDefVal:
break;
case TAGDefCon:
case TAGDefTyp:
default:
badtag (d -> tag);
break;
};
};
};
/*
Expand thedef
*/
static val expand_val ();
static val_list expand_val_list ();
static def expand_thedef (d)
def d;
{ val newrhs;
val rhs = d -> DefVal.valas;
if (rhs -> tag != TAGVLambda)
{ fprintf (stderr, "Lambda abstractor expected\n");
exit (1);
};
newrhs = new_VLambda (rdup_formcon (rhs -> VLambda.lpar),
expand_val (rhs -> VLambda.lval));
return (new_DefVal (rdup_orig (d -> DefVal.valorig),
rdup_symbol (d -> DefVal.valnm),
rdup_typ (d -> DefVal.valtyp), newrhs));
};
static val formcon_to_val (fc)
formcon fc;
{ switch (fc -> tag)
{ case TAGFCSym:
return (new_VSym (rdup_orig (thedef -> DefVal.valorig),
rdup_symbol (fc -> FCSym.sym)));
case TAGFCList:
{ val_list vl = new_val_list ();
formcon_list fcl = fc -> FCList.l;
if ((fcl != formcon_listNIL) && (fcl -> sz != 0))
{ register int ix;
room_val_list (vl, fcl -> sz);
vl -> sz = fcl -> sz;
for (ix=0; ix < fcl -> sz; ix++)
vl -> arr[ix] = formcon_to_val (fcl -> arr[ix]);
};
return (new_VList (vl));
};
default: badtag (fc -> tag);
};
};
static val try_subst (expr, fc, arg)
val expr;
formcon fc;
val arg;
{ switch (fc -> tag)
{ case TAGFCSym:
return (subs_val (fc -> FCSym.sym, arg, expr));
case TAGFCList:
{ formcon_list fcl = fc -> FCList.l;
def_list dl;
if ((fcl == formcon_listNIL) || (fcl -> sz == 0))
return (rdup_val (expr));
if ((arg -> tag == TAGVList) &&
(arg -> VList.l -> sz == fcl -> sz))
{ /* formal and actuals match... */
register int ix;
val new = rdup_val (expr);
for (ix = 0; ix < fcl -> sz; ix++)
{ val prev = new;
new = try_subst (prev, fcl -> arr[ix],
arg -> VList.l -> arr[ix]);
rfre_val (prev);
};
return (new);
};
dl = new_def_list ();
app_def_list (dl, new_DefCon
(rdup_orig (thedef -> DefVal.valorig),
formcon_to_val (fc),
rdup_val (arg)));
return (new_VWhere (dl, rdup_val (expr)));
};
default: badtag (fc -> tag);
};
};
static val beta_reduce (lab, arg)
val lab,arg;
{ val expr = rdup_val (lab -> VLambda.lval);
val mexpr = try_subst (expr, lab -> VLambda.lpar, arg);
val texpr = expand_val (mexpr);
rfre_val (expr);
rfre_val (mexpr);
return (texpr);
};
static val expand_application (v)
val v;
{ val appsys = v -> VApply.aval;
val args = v -> VApply.apar;
switch (appsys -> tag)
{ case TAGVSym:
{ def found = find_def (appsys -> VSym.sym);
if (found == defNIL)
{ fprintf (stderr, "Definition not found\n");
exit (1);
};
if ((found -> tag != TAGDefVal) ||
(found -> DefVal.valas -> tag != TAGVLambda))
{ fprintf (stderr, "Wrong definition found\n");
exit (1);
};
return (beta_reduce (found -> DefVal.valas, args));
};
case TAGVLambda:
return (beta_reduce (appsys, args));
case TAGVSigma:
{ fprintf (stderr, "Only directional systems allowed\n");
exit (1);
};
default: badtag (appsys -> tag);
};
};
static int def_may_be_deleted (d)
def d;
{ val lhs = d -> DefCon.defcon;
val rhs = d -> DefCon.conas;
if (lhs -> tag == TAGVList)
{ val_list vl = lhs -> VList.l;
if (vl -> sz == 0) return (1);
};
if (rhs -> tag == TAGVList)
{ val_list vl = rhs -> VList.l;
if (vl -> sz == 0) return (1);
};
return (0);
};
static val expand_wheres (v)
val v;
{ def_list wdefs = v -> VWhere.wdefs;
def_list ndefs;
val newval;
register int ix;
if ((wdefs == def_listNIL) || (wdefs -> sz == 0))
return (expand_val (v -> VWhere.wval));
ins_ctx_list (context, 0, new_ctx (rdup_def_list (wdefs)));
ndefs = new_def_list ();
for (ix=0; ix < wdefs -> sz; ix++)
{ def d = wdefs -> arr[ix];
switch (d -> tag)
{ case TAGDefBasetype:
case TAGDefAtom:
app_def_list (new_defs, rdup_def (d));
break;
case TAGDefVal:
break;
case TAGDefCon:
if (!def_may_be_deleted (d))
app_def_list (ndefs, new_DefCon
(rdup_orig (d -> DefCon.conorig),
rdup_val (d -> DefCon.defcon),
expand_val (d -> DefCon.conas)));
break;
default:
badtag (d -> tag);
};
};
if (ndefs -> sz == 0)
{ newval = expand_val (v -> VWhere.wval);
rfre_def_list (ndefs);
}
else
newval = new_VWhere (ndefs, expand_val (v -> VWhere.wval));
del_ctx_list (context, 0);
return (newval);
};
static val expand_val (v)
val v;
{ switch (v -> tag)
{ case TAGVSym:
return (rdup_val (v));
case TAGVLambda:
{ fprintf (stderr, "All abstractors should have vanished\n");
exit (1);
};
case TAGVApply:
return (expand_application (v));
case TAGVWhere:
return (expand_wheres (v));
case TAGVList:
return (new_VList (expand_val_list (v -> VList.l)));
case TAGVAtom:
return (new_VAtom (rdup_orig (v -> VAtom.atorig),
rdup_symbol (v -> VAtom.atnm),
rdup_parval_list (v -> VAtom.atvpar),
expand_val (v -> VAtom.atcpar)));
case TAGVAppset:
case TAGVSigma:
case TAGVSyn:
{ fprintf (stderr, "Only directional systems allowed\n");
exit (1);
};
default:
badtag (v -> tag);
};
};
static val_list expand_val_list (vl)
val_list vl;
{ register int ix;
val_list new = new_val_list ();
for (ix = 0; ix < vl -> sz; ix++)
app_val_list (new, expand_val (vl -> arr[ix]));
return (new);
};
/* Print usage of this program */
static void usage (f)
FILE *f;
{ fprintf (f, "Usage: gen [-d<debugging flags>]\n");
helpdbflags (f, flagtab);
};
/* scan arguments and options */
static void scanargs (argc, argv)
int argc;
char *argv[];
{ int op;
argv++;
argc--;
while (argc>0)
{ if (argv[0][0] != '-')
{ fprintf (stderr, "too many arguments\n");
usage (stderr);
exit (1);
};
op = argv[0][1];
switch (op)
{ case 'd': setdbflags (&argv[0][2], flagtab, TRUE);
break;
case 'h':
case 'H': usage (stdout);
exit (0);
case 'o': showorig = FALSE;
break;
default: usage (stderr);
exit (1);
};
argc--;
argv++;
};
};
static def find_thedef (dl)
def_list dl;
{ register int ix;
register def d;
register def mdef = defNIL;
for (ix = 0; ix < dl -> sz; ix++)
{ d = dl -> arr[ix];
if (d -> tag == TAGDefVal) mdef = d;
};
if (mdef == defNIL)
{ fprintf ("No expandible definition found\n");
exit (1);
};
return (mdef);
};
main (argc, argv)
int argc;
char *argv [];
{ def_list all_defs;
initsymbol ();
scanargs (argc, argv);
tmlineno = 1;
fprintf (stderr, "uflat: loading...\n");
if (fscan_def_list (infile, &all_defs))
{ fprintf (stderr, "Read error: (%d): %s\n", tmlineno, tmerrmsg);
exit (1);
};
thedef = find_thedef (all_defs);
new_defs = new_def_list ();
context = new_ctx_list ();
ins_ctx_list (context, 0, new_ctx (rdup_def_list (all_defs)));
fprintf (stderr, "uflat: expanding...\n");
copy_basenamedefs (new_defs, all_defs);
app_def_list (new_defs, expand_thedef (thedef));
rfre_ctx_list (context);
fprint_def_list (outfile, new_defs);
if (stat)
{ rfre_def_list (new_defs);
rfre_def_list (all_defs);
flushsymbol ();
stat_ds (stderr);
stat_string (stderr);
};
}